﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;

namespace IGGCore
{
    /// <summary>
    /// 1 - ADD RANKINGS
    /// 2 - GET TIDBIT
    /// 2.1 - GET RANDOM RANKING
    /// 2.1.1 - IS IT CACHED FOR TODAY?
    /// 2.2 - PARSE RANKING
    /// 2.3 - GET RANDOM PRESENTATION
    /// 2.4 - PREPARE AND RETURN STRING
    /// </summary>
    public class BaseballReferenceParser : BaseParser
    {
        public enum PRESENTATIONS { MILESTONES, TOP5, TOP10, RANDOMTOP100, RANDOMTOP10, RANDOMTOP50};
        public enum STATS_TYPES { ACTIVE, CAREER, SEASON };

        private List<RankedPlayer> RankedPlayersRankingBucket = new List<RankedPlayer>();
        private Random rnd                                    = new Random();
        private List<Rankings> m_rankings                     = new List<Rankings>();

        public BaseballReferenceParser()
        {
            // BATTING AVERAGE
            m_rankings.Add(new Rankings("Batting Avg", "http://www.baseball-reference.com/leaders/batting_avg_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Batting Avg", "http://www.baseball-reference.com/leaders/batting_avg_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Batting Avg", "http://www.baseball-reference.com/leaders/batting_avg_season.shtml", STATS_TYPES.SEASON));
            // WAR
            m_rankings.Add(new Rankings("WAR", "http://www.baseball-reference.com/leaders/WAR_bat_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("WAR", "http://www.baseball-reference.com/leaders/WAR_bat_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("WAR", "http://www.baseball-reference.com/leaders/WAR_bat_season.shtml", STATS_TYPES.SEASON));
            // ON BASE PERCENTAGE
            m_rankings.Add(new Rankings("On Base %", "http://www.baseball-reference.com/leaders/onbase_perc_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("On Base %", "http://www.baseball-reference.com/leaders/onbase_perc_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("On Base %", "http://www.baseball-reference.com/leaders/onbase_perc_season.shtml", STATS_TYPES.SEASON));
            // SLUGGING PERCENTAGE
            m_rankings.Add(new Rankings("Slugging", "http://www.baseball-reference.com/leaders/slugging_perc_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Slugging", "http://www.baseball-reference.com/leaders/slugging_perc_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Slugging", "http://www.baseball-reference.com/leaders/slugging_perc_season.shtml", STATS_TYPES.SEASON));
            // ON BASE PLUS SLUGGING PERCENTAGE
            m_rankings.Add(new Rankings("On Base + Slugging", "http://www.baseball-reference.com/leaders/onbase_plus_slugging_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("On Base + Slugging", "http://www.baseball-reference.com/leaders/onbase_plus_slugging_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("On Base + Slugging", "http://www.baseball-reference.com/leaders/onbase_plus_slugging_season.shtml", STATS_TYPES.SEASON));
            // HITS
            m_rankings.Add(new Rankings("Hits", "http://www.baseball-reference.com/leaders/H_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Hits", "http://www.baseball-reference.com/leaders/H_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Hits", "http://www.baseball-reference.com/leaders/H_season.shtml", STATS_TYPES.SEASON));
            // BASE ON BALLS
            m_rankings.Add(new Rankings("Base on balls", "http://www.baseball-reference.com/leaders/BB_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Base on balls", "http://www.baseball-reference.com/leaders/BB_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Base on balls", "http://www.baseball-reference.com/leaders/BB_season.shtml", STATS_TYPES.SEASON));
            // HOMERUNS
            m_rankings.Add(new Rankings("Homeruns", "http://www.baseball-reference.com/leaders/HR_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Homeruns", "http://www.baseball-reference.com/leaders/HR_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Homeruns", "http://www.baseball-reference.com/leaders/HR_season.shtml", STATS_TYPES.SEASON));
            // WINS
            m_rankings.Add(new Rankings("Wins", "http://www.baseball-reference.com/leaders/W_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Wins", "http://www.baseball-reference.com/leaders/W_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Wins", "http://www.baseball-reference.com/leaders/W_season.shtml", STATS_TYPES.SEASON));
            // RBI
            m_rankings.Add(new Rankings("RBI", "http://www.baseball-reference.com/leaders/RBI_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("RBI", "http://www.baseball-reference.com/leaders/RBI_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("RBI", "http://www.baseball-reference.com/leaders/RBI_season.shtml", STATS_TYPES.SEASON));
            // STOLEN BASES
            m_rankings.Add(new Rankings("Stolen Bases", "http://www.baseball-reference.com/leaders/SB_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Stolen Bases", "http://www.baseball-reference.com/leaders/SB_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Stolen Bases", "http://www.baseball-reference.com/leaders/SB_season.shtml", STATS_TYPES.SEASON));
            // STRIKEOUTS
            m_rankings.Add(new Rankings("Strikeouts", "http://www.baseball-reference.com/leaders/SO_p_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Strikeouts", "http://www.baseball-reference.com/leaders/SO_p_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Strikeouts", "http://www.baseball-reference.com/leaders/SO_p_season.shtml", STATS_TYPES.SEASON));
            // SAVES
            m_rankings.Add(new Rankings("Saves", "http://www.baseball-reference.com/leaders/SV_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Saves", "http://www.baseball-reference.com/leaders/SV_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Saves", "http://www.baseball-reference.com/leaders/SV_season.shtml", STATS_TYPES.SEASON));
            // GAMES PLAYED
            m_rankings.Add(new Rankings("Games played", "http://www.baseball-reference.com/leaders/G_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Games played", "http://www.baseball-reference.com/leaders/G_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Games played", "http://www.baseball-reference.com/leaders/G_season.shtml", STATS_TYPES.SEASON));
            // AT BATS
            m_rankings.Add(new Rankings("At bats", "http://www.baseball-reference.com/leaders/AB_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("At bats", "http://www.baseball-reference.com/leaders/AB_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("At bats", "http://www.baseball-reference.com/leaders/AB_season.shtml", STATS_TYPES.SEASON));
            // COMPLETE GAMES
            m_rankings.Add(new Rankings("Complete games", "http://www.baseball-reference.com/leaders/CG_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Complete games", "http://www.baseball-reference.com/leaders/CG_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Complete games", "http://www.baseball-reference.com/leaders/CG_season.shtml", STATS_TYPES.SEASON));
            // TRIPLES
            m_rankings.Add(new Rankings("Triples", "http://www.baseball-reference.com/leaders/3B_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Triples", "http://www.baseball-reference.com/leaders/3B_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Triples", "http://www.baseball-reference.com/leaders/3B_season.shtml", STATS_TYPES.SEASON));
            // DOUBLES
            m_rankings.Add(new Rankings("Doubles", "http://www.baseball-reference.com/leaders/2B_active.shtml", STATS_TYPES.ACTIVE));
            m_rankings.Add(new Rankings("Doubles", "http://www.baseball-reference.com/leaders/2B_career.shtml", STATS_TYPES.CAREER));
            m_rankings.Add(new Rankings("Doubles", "http://www.baseball-reference.com/leaders/2B_season.shtml", STATS_TYPES.SEASON));
        }

        /// <summary>
        /// Parse the Baseball Reference website for rankings
        /// </summary>
        public void ParseReference()
        {
            //Rankings rank = m_rankings[rnd.Next(m_rankings.Count)];
            //m_rankings.Remove(rank);
            //AddRanking(rank);
        }


        /// <summary>
        /// Return a ranking info
        /// </summary>
        public void SetRankingTidbit(Scoreboard board)
        {
            // MILESTONE. A PLAYER IS NEAR ONE
            // TOP 5 ACTIVE PLAYERS
            // TOP 5 PLAYERS OF ALL TIME
            // RANDOM TOP 100 ACTIVE PLAYER IN A CATEGORY
            // RANDOM TOP 100 ALL-TIME PLAYER IN A CATEGORY

            // 1 - ADD RANKINGS (DONE!)
            // 2 - GET TIDBIT (DONE!)
            // 2.1 - GET RANDOM RANKING (DONE!)
            Rankings rankings = m_rankings[rnd.Next(m_rankings.Count)];

            // 2.1.1 - IS IT CACHED FOR TODAY? (DONE!)
            // 2.1.1.1 - In Memory? On Files? If so, skip 2.2
            if (rankings.Players == null) 
            {
                // 2.2 - PARSE RANKING (DONE!)
                rankings.Players = GetRankedPlayers(rankings.URL, rankings.Subject);
            }
            if (rankings.Players.Count == 0)
            {
                rankings.Players = null;
                return;
            }

            // 2.3 - GET RANDOM PRESENTATION (DONE!)
            Array values = Enum.GetValues(typeof(PRESENTATIONS));
            Random random = new Random();
            PRESENTATIONS randomPresentation = (PRESENTATIONS)values.GetValue(random.Next(values.Length));
            
            while (randomPresentation == PRESENTATIONS.MILESTONES && rankings.StatsTypes != STATS_TYPES.ACTIVE)
            {
                randomPresentation = (PRESENTATIONS)values.GetValue(random.Next(values.Length));
            }

            // 2.4 - PREPARE AND RETURN STRING
            board.BaseballRefTidbit = GetPreparedRankings(rankings, randomPresentation);
        }

        private string GetPreparedRankings(Rankings rankings, PRESENTATIONS presentation)
        {
            string result = "";
            result = " All-Time " + rankings.Subject + " Leaders" + Environment.NewLine;
            if (rankings.StatsTypes == STATS_TYPES.SEASON)
            {
                result = " " + rankings.Subject + " Leaders For a Single Season" + Environment.NewLine;
            }
            else if (rankings.StatsTypes == STATS_TYPES.ACTIVE)
            {
                result = " Active " + rankings.Subject + " Leaders" + Environment.NewLine;
            }
            string activest = "";
            if (rankings.StatsTypes == STATS_TYPES.ACTIVE)
            {
                activest = " amongst active players";
            }
            else if (rankings.StatsTypes == STATS_TYPES.SEASON)
            {
                activest = " for a single season";
            }
            switch (presentation)
            {
                case PRESENTATIONS.MILESTONES:
                    {
                        if (rankings.Players[0].Details.Contains(".") == false)
                        {
                            List<RankedPlayer> nearPlayer = Analyze(rankings.Players);
                            KeepNearest(nearPlayer, 6);
                            RankedPlayer player = nearPlayer[rnd.Next(nearPlayer.Count)];
                            if (player.Delta > 0)
                            {
                                result = " " + player.Name + " is " + player.Delta + " " + player.Subject.ToLower() + " away from "
                                    + (int.Parse(player.Details) + player.Delta);
                            }
                            else
                            {
                                result = " " + player.Name + " has " + int.Parse(player.Details) + " " + player.Subject.ToLower();
                            }
                            result += ". He is currently ranked " + player.Rank + getNumberSuffix(int.Parse(player.Rank)) + " amongst active players.";
                        }
                        else
                        {
                            result = " No Milestones For YOU!";
                        }

                        break;
                    }
                case PRESENTATIONS.TOP5:
                    {
                        for (int i = 0; i < 5; i++)
                        {
                            string year = "";
                            if (rankings.Players[i].Year != null && rankings.StatsTypes == STATS_TYPES.SEASON)
                            {
                                year = " (" + rankings.Players[i].Year + ")";
                            }
                            result += " " + (i + 1) + "- " + rankings.Players[i].Name.PadRight(20) + rankings.Players[i].Details + year + Environment.NewLine;
                        }
                        break;
                    }
                case PRESENTATIONS.TOP10:
                    {
                        for (int i = 0; i < 10; i++)
                        {
                            string year = "";
                            if (rankings.Players[i].Year != null && rankings.StatsTypes == STATS_TYPES.SEASON)
                            {
                                year = " (" + rankings.Players[i].Year + ")";
                            }
                            result += " " + (i + 1).ToString().PadRight(2) + "- " + rankings.Players[i].Name.PadRight(20) + rankings.Players[i].Details + year + Environment.NewLine;
                        }
                        break;
                    }
                case PRESENTATIONS.RANDOMTOP10:
                    {
                        string year = "";
                        RankedPlayer player = rankings.Players[rnd.Next(10)];
                        if (rankings.StatsTypes == STATS_TYPES.SEASON)
                        {
                            year = ". He did it in " + player.Year;
                        }
                        result = " " + player.Name + " is ranked " + player.Rank + getNumberSuffix(int.Parse(player.Rank)) + activest + " in " + rankings.Subject.ToLower() + " with " + player.Details + year;
                        break;
                    }
                case PRESENTATIONS.RANDOMTOP100:
                    {
                        string year = "";
                        RankedPlayer player = null;
                        if (rankings.Players.Count >= 100)
                        {
                            player = rankings.Players[rnd.Next(100)];
                        }
                        else
                        {
                            player = rankings.Players[rnd.Next(rankings.Players.Count)];
                        }
                        if (rankings.StatsTypes == STATS_TYPES.SEASON)
                        {
                            year = ". He did it in " + player.Year;
                        }
                        result = " " + player.Name + " is ranked " + player.Rank + getNumberSuffix(int.Parse(player.Rank)) + activest + " in " + rankings.Subject.ToLower() + " with " + player.Details + year;
                        break;
                    }
                case PRESENTATIONS.RANDOMTOP50:
                    {
                        string year = "";
                        RankedPlayer player = null;
                        if (rankings.Players.Count >= 50)
                        {
                            player = rankings.Players[rnd.Next(50)];
                        }
                        else
                        {
                            player = rankings.Players[rnd.Next(rankings.Players.Count)];
                        }
                        if (rankings.StatsTypes == STATS_TYPES.SEASON)
                        {
                            year = ". He did it in " + player.Year;
                        }
                        result = " " + player.Name + " is ranked " + player.Rank + getNumberSuffix(int.Parse(player.Rank)) + activest + " in " + rankings.Subject.ToLower() + " with " + player.Details + year;
                        break;
                    }
                default:
                    for (int i = 0; i < 5; i++)
                    {
                        result += " " + (i + 1) + "- " + rankings.Players[i].Name.PadRight(20) + rankings.Players[i].Details + Environment.NewLine;
                    }
                    break;
            }
            return result;
        }

        /// <summary>
        /// Add ranking
        /// </summary>
        private void AddRanking(Rankings ranking)
        {
            List<RankedPlayer> players = GetRankedPlayers(ranking.URL, ranking.Subject);
            List<RankedPlayer> nearPlayer = Analyze(players);
            KeepNearest(nearPlayer, 3);
            RankedPlayersRankingBucket.AddRange(nearPlayer);
        }


        /// <summary>
        /// Extract the ranking content from the website raw source
        /// </summary>
        private string GetRankingContent(string rawcontent)
        {
            string transContent = rawcontent.Substring(rawcontent.IndexOf("<div id=\"page_content\">"));
            transContent = transContent.Substring(transContent.IndexOf("<tr><td align=right>1."));
            transContent = transContent.Substring(0, transContent.IndexOf("</table>"));
            int index = transContent.IndexOf("<thead>");
            int endindex = transContent.IndexOf("</thead>") + "</thead>".Length;
            if (index > -1)
            {
                transContent = transContent.Remove(index, endindex - index);
            }
            return transContent;
        }

        /// <summary>
        /// Get the Ranked Players for this subject
        /// </summary>
        private List<RankedPlayer> GetRankedPlayers(string url, string subject)
        {
            List<RankedPlayer> rankedPlayers = new List<RankedPlayer>();
            try
            {
                string transContent = GetRankingContent(GetAllContent(url));
                string[] players = transContent.Split(new string[] { "</tr>" }, StringSplitOptions.RemoveEmptyEntries);
                string lastValidRank = "";


                foreach (string player in players)
                {
                    if (player.Length < 10 || player.Contains("Rank"))
                    {
                        continue;
                    }
                    RankedPlayer rankedPlayer = new RankedPlayer();
                    rankedPlayer.Subject = subject;

                    // rank
                    string rank = "1";
                    int indexPoint = player.IndexOf(".");
                    if (indexPoint > 0)
                    {
                        int indexBefore = player.Substring(0, indexPoint).LastIndexOf(">") + 1;
                        rank = player.Substring(indexBefore, indexPoint - indexBefore);
                        try
                        {
                            int ranint = int.Parse(rank);
                            lastValidRank = rank;
                        }
                        catch
                        {
                            rank = lastValidRank;
                        }

                    }
                    else if (player.IndexOf(";") > 0)
                    {
                        rank = lastValidRank;
                    }
                    rankedPlayer.Rank = rank;



                    // name
                    // active players have <strong> tags
                    int indexfirst = player.IndexOf("<strong>") + "<strong>".Length;
                    int indexlast = player.IndexOf("</strong>");
                    if (indexlast > -1)
                    {
                        rankedPlayer.Name = player.Substring(indexfirst, indexlast - indexfirst).Replace("&nbsp;", " ");
                    }
                    else
                    {
                        indexfirst = player.IndexOf("\">") + "\">".Length;
                        indexlast = player.IndexOf("</a>");
                        rankedPlayer.Name = player.Substring(indexfirst, indexlast - indexfirst).Replace("&nbsp;", " ");
                    }
                    rankedPlayer.Name = rankedPlayer.Name.Replace("+", "");

                    // age season
                    indexfirst = player.IndexOf("</a>&nbsp;") + "</a>&nbsp;".Length;
                    string content = player.Substring(indexfirst);
                    indexlast = content.IndexOf("</td>");
                    string[] ageseason = content.Substring(1, indexlast - 2).Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    rankedPlayer.Seasons = ageseason[0];
                    if (ageseason.Length > 1)
                    {
                        rankedPlayer.Age = ageseason[1];
                    }

                    // details
                    indexfirst = content.IndexOf("right>") + "right>".Length;
                    content = content.Substring(indexfirst);
                    indexlast = content.IndexOf("</td>");
                    rankedPlayer.Details = content.Substring(0, indexlast);
                    content = content.Substring(indexlast);

                    // year
                    indexfirst = content.IndexOf("right>") + "right>".Length;
                    if (indexfirst > -1)
                    {
                        content = content.Substring(indexfirst);
                        indexlast = content.IndexOf("</td>");
                        rankedPlayer.Year = content.Substring(0, indexlast);
                        content = content.Substring(indexlast);
                    }


                    rankedPlayers.Add(rankedPlayer);
                }
            }
            catch (Exception ex)
            {
                new Exception("ERROR WITH RANKING " + subject + " and URL " + url, ex);
            }
            return rankedPlayers;
        }

        private void KeepNearest(List<RankedPlayer> players, int max)
        {
            while (players.Count > max)
            {
                int maxi = -1;
                int count = 0;
                foreach (RankedPlayer player in players)
                {
                    count++;
                    if (count > 3 && player.Delta > maxi)
                    {
                        maxi = player.Delta;
                        players.Remove(player);
                        break;
                    }
                    else if (count > max)
                    {
                        players.Remove(player);
                        players.Insert(0, player);
                        break;
                    }
                    else if (player.Delta > maxi)
                    {
                        maxi = player.Delta;
                    }
                }
            }
        }

        private string getNumberSuffix(int num)
        {
            string suffix = "th";
            if (num == 1 || num == 21 || num == 31 || num == 41)
            {
                suffix = "st";
            }
            else if (num == 2 || num == 22 || num == 32 || num == 42)
            {
                suffix = "nd";
            }
            else if (num == 3 || num == 23 || num == 33 || num == 43)
            {
                suffix = "rd";
            }
            return suffix;
        }

        private int GetCeiling(int num, int smallCeiling)
        {
            return (int)(Math.Ceiling((float)num / (float)smallCeiling) * smallCeiling);
        }

        /// <summary>
        /// Analyze rankings to find players near milestones
        /// </summary>
        private List<RankedPlayer> Analyze(List<RankedPlayer> players)
        {
            int bigCeiling = 0;
            int smallCeiling = 1000;
            int dynDelta = 3;

            if (players[0].Details[0] != '.')
            {
                int max = int.Parse(players[0].Details);
                // GET NEARER ROUND NUMBER (256 --> 300; 1567 --> 2000; 3899 --> 4000)
                if (max < 100)
                {
                    bigCeiling = (int)(Math.Ceiling(max / 10.0) * 10);
                    smallCeiling = 10;
                    dynDelta = 3;
                }
                else if (max < 1000)
                {
                    bigCeiling = (int)(Math.Ceiling(max / 100.0) * 100);
                    smallCeiling = 100;
                    dynDelta = 10;
                }
                else
                {
                    bigCeiling = (int)(Math.Ceiling(max / 1000.0) * 1000);
                    smallCeiling = 500;
                    dynDelta = 100;
                }
            }

            List<RankedPlayer> finalplayers = new List<RankedPlayer>();
            foreach (RankedPlayer player in players)
            {
                int num = int.Parse(player.Details);
                int persCeiling = GetCeiling(num, smallCeiling);
                if ((persCeiling - num) <= dynDelta)
                {
                    player.Delta = (persCeiling - num);
                    finalplayers.Add(player);
                }
            }
            return finalplayers;
        }

        /// <summary>
        /// Get the complete source of a specified website url
        /// </summary>
        private string GetAllContent(string url)
        {
            string transContent = null;
            StreamReader reader = null;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                reader = new StreamReader(request.GetResponse().GetResponseStream());
                transContent = reader.ReadToEnd();
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
            }
            return transContent;
        }

        public class Rankings
        {
            public string Subject { get; set; }
            public string URL { get; set; }
            public bool Loaded { get; set; }
            public List<RankedPlayer> Players { get; set; }
            public STATS_TYPES StatsTypes { get; set; }

            public Rankings(string subject, string url, STATS_TYPES type)
            {
                Subject = subject;
                URL = url;
                Loaded = false;
                Players = null;
                StatsTypes = type;
            }

        }


        /// <summary>
        /// The ranked player container class
        /// </summary>
        public class RankedPlayer
        {
            public string Subject { get; set; }
            public string Rank { get; set; }
            public string Name {get;set;}
            public string Age { get; set; }
            public string Year { get; set; }
            public string Seasons { get; set; }
            public string Details { get; set; }
            public int Delta { get; set; }
        }
    }
}
